package com.kgis.map.tile {
    import com.kgis.map.events.TileEvent;
    import com.kgis.map.geometry.basetype.Extent;
    import com.kgis.map.geometry.basetype.Location;
    import com.kgis.map.geometry.basetype.Pixel;
    import com.kgis.map.geometry.basetype.Size;
    import com.kgis.map.layer.Layer;
    import flash.display.Sprite;

    /**
     *  瓦片类
     */
    public class Tile extends Sprite {
        private var _layer:Layer = null;
        private var _url:String = null;
        private var _bounds:Extent = null;
        private var _size:Size = null;
        private var _drawn:Boolean = false;
        private var _onLoadStart:Function = null;
        private var _onLoadEnd:Function = null;
        private var _loading:Boolean = false;
        protected var _drawPosition:Pixel = null;

        public function Tile(layer:Layer, position:Pixel, bounds:Extent, url:String, size:Size) {
            this.layer = layer;
            this.position = position;
            this.bounds = bounds;
            this.url = url;
            this.size = size;
        }

        public function destroy():void {
            this.layer = null;
            this.bounds = null;
            this.size = null;
            this.position = null;
        }

        /**
         * 绘制瓦片
         */
        public function draw():void {
        }

        public function withinMapBounds():Boolean {
            return (this.layer.map.maxExtent && this.layer.map.maxExtent.containsBounds(this.bounds, true, true));
        }

        public function moveTo(bounds:Extent, position:Pixel, redraw:Boolean = true):void {
            this.bounds = bounds.clone();

            _drawPosition = position.clone();
            this.url = this.layer.getURL(this.bounds);

            if (redraw) {
                this.draw();
            }
        }

        /**/ /**
         * Reposition the tile.
         *
         * @param bounds
         * @param position
         * @param redraw
         */
        public function clearAndMoveTo(bounds:Extent, position:Pixel, redraw:Boolean = true):void {
            this.clear();
            this.bounds = bounds.clone();
            this.position = position.clone();
            _drawPosition = null;
            this.url = this.layer.getURL(this.bounds);
            if (redraw) {
                this.draw();
            }
        }

        public function clear():void {
            this.drawn = false;
        }

        /**
         * 根据瓦片左上角在layer上的像素坐标，计算瓦片的bounds
         * @param 左上角的layer像素坐标
         * @return 瓦片bounds
         */
        public function getBoundsFromTopLeftPixel(position:Pixel):Extent {
            var topLeft:Location = this.layer.map.getLocationFromLayerPx(position);
            var bottomRightPx:Pixel = position.clone();
            bottomRightPx.x += this.size.w;
            bottomRightPx.y += this.size.h;
            var bottomRight:Location = this.layer.map.getLocationFromLayerPx(bottomRightPx);
            /*			if (topLeft.lon > bottomRight.lon) {
               if (topLeft.lon < 0) {
               topLeft = new Location(-180 - (topLeft.lon+180), topLeft.x,topLeft.projection);
               } else {
               bottomRight = new Location(180+bottomRight.lon+180, bottomRight.y, bottomRight.projection);
               }
             }*/
            bounds = new Extent(topLeft.lon, bottomRight.lat, bottomRight.lon, topLeft.lat);
            return bounds;
        }

        public function get position():Pixel {
            return new Pixel(this.x, this.y);
        }

        public function set position(value:Pixel):void {
            if (value) {
                this.x = value.x;
                this.y = value.y;
            }
        }

        //Getters and Setters
        public function get layer():Layer {
            return this._layer;
        }

        public function set layer(value:Layer):void {
            this._layer = value;
        }

        public function get url():String {
            return this._url;
        }

        public function set url(value:String):void {
            this._url = value;
        }

        public function get bounds():Extent {
            return this._bounds;
        }

        public function set bounds(value:Extent):void {
            this._bounds = value;
        }

        public function get size():Size {
            return this._size;
        }

        public function set size(value:Size):void {
            this._size = value;
        }

        public function get drawn():Boolean {
            return this._drawn;
        }

        public function set drawn(value:Boolean):void {
            this._drawn = value;
        }

        public function get onLoadStart():Function {
            return this._onLoadStart;
        }

        public function set onLoadStart(value:Function):void {
            this._onLoadStart = value;
        }

        public function get onLoadEnd():Function {
            return this._onLoadEnd;
        }

        public function set onLoadEnd(value:Function):void {
            this._onLoadEnd = value;
        }

        /**
         * 是否load完成
         */
        public function get loadComplete():Boolean {
            return !this._loading;
        }

        /**
         * tile的load状态
         */
        protected function set loading(value:Boolean):void {
            if (value == true && this._loading == false) {
                this._loading = value;
                // 通知图层tile load开始消息
                this.layer.dispatchEvent(new TileEvent(TileEvent.TILE_LOAD_START, this));
            }

            if (value == false && this._loading == true && this.layer != null) { // this.layer can be null, if you're unlucky and removed layer before it was totally loaded
                this._loading = value;
                // tile load结束			
                this.layer.dispatchEvent(new TileEvent(TileEvent.TILE_LOAD_END, this));
            }
        }
    }
}